from flask import Blueprint, render_template, request, g, redirect, url_for
from blueprints.forms import QuestionForm, AnswerForm
from models import QuestionModel, AnswerModel
from exts import db
from decorators import login_required

bp = Blueprint("qa", __name__, url_prefix="/")


# 首页: 127.0.0.1:5000
@bp.route("/")
def index():
    # 获取表中所有的问答,并传给前端页面
    questions = QuestionModel.query.order_by(QuestionModel.create_time.desc()).all()
    return render_template("index.html", questions=questions)


# 问答首页
@bp.route("/qa/public", methods=["GET", "POST"])
@login_required
def public_question():
    # 这两行代码用装饰器代替
    # if not g.user:
    #     return render_template(url_for("auth.login"))
    if request.method == "GET":
        return render_template("public_question.html")
    else:
        # 1、把前端表单数据传入验证表单，并生成验证表单实例对象
        form = QuestionForm(request.form)
        # 2、开始验证实例对象
        if form.validate():
            # 3、获得前端form字段数据，并生成实例对象
            title = form.title.data
            content = form.content.data
            # 4、生成问答模型实例对象，并同步到数据库，其中author值是g.user当前登录的用户
            question = QuestionModel(title=title, content=content, author=g.user)
            db.session.add(question)
            db.session.commit()
            # todo:跳转到这篇问答的详情页
            # 5、跳转到首页
            return redirect("/")
        else:
            # 6、表单验证失败，返回报错 and 跳转到发布页
            print(form.errors)
            return redirect(url_for("qa.public_question"))


@bp.route("/qa/detail/<qa_id>")
def qa_detail(qa_id):
    question = QuestionModel.query.get(qa_id)
    return render_template("detail.html", question=question)


# @bp.route("/answer/public", methods=["POST"])
@bp.post("/answer/public")  # 最新写法，作用与上面相同
@login_required  # 5、验证用户是否登录：添加登录请求装饰器
def public_answer():
    # 1、生成表单对象，并传入验证参数
    form = AnswerForm(request.form)
    # 2、表单验证
    if form.validate():
        # 3、获得表单数据
        content = form.content.data
        question_id = form.question_id.data
        # 4、生成表单对象
        answer = AnswerModel(content=content, question_id=question_id, author_id=g.user.id)
        # 6、并提交给数据库
        db.session.add(answer)
        db.session.commit()
        # 7、返回问答详情页
        return redirect(url_for("qa.qa_detail", qa_id=question_id))
    else:
        # 8、验证不通过，返回报错和详情页
        print("表单验证失败！", form.errors)
        # 不用form.get("question_id")，是因为报错form对象可能没有question_id
        return redirect(url_for("qa.qa_detail", qa_id=request.form.get("question_id")))


@bp.route("/search")
def search():
    # 传参方式有三种
    # 1) 查询字符串的形式把参数传到视图函数中：/search?q=flask
    # 2) 直接把关键字参数固定到路径中，作为url的一部分：/search/<q>
    # 3) post,request.form:通过post提交参数，然后从request.form中获取
    # 1、获取from表单参数
    q = request.args.get("q")
    # 2、在quertionModel表中查询标题包含q的问答; (filter:模糊查询，filter_by:精确查询)
    questions = QuestionModel.query.filter(QuestionModel.title.contains(q)).all()
    # 3、查询后返回首页
    return render_template("index.html", questions=questions)

# url传参
# 邮件发送
# ajax
# orm与数据库
# jinjia2模板
# cookie session
# 搜索

# 前端
# 部署：比如部署到阿里云； excel文件上传下载
# flask全栈开发：flask增强+前端
# flask实战：flask+vue前后端分离的论坛系统，websocket实战
